
/**
 * 经纬度获取
 *
 * @param {*} i
 * @param {*} v
 * @return {*} 
 */
export const getLocation = (i: number, v: DataView) => {
    return {
        longitude: parseFloat(v.getBigInt64(i, true) / BigInt(10000000) + ''),
        latitude: parseFloat(v.getBigInt64(i += 8, true) / BigInt(10000000) + ''),
        height: v.getUint16(i += 8, true)
    }
}


/**
 * 补零
 *
 * @param {*} num
 * @return {*} 
 */
export const reZero = (num: number | string): number | string => {
    if (num < 10) return '0' + num
    else return num + ''
};

/**
 * 双位数补零
 *
 * @param {*} num
 * @return {*} 
 */
export const reDoubleZero = (num: number | string): number | string => {
    if (num < 10) return '00' + num
    if (num < 100) return '0' + num
    else return num + ''
};

/**
 * 时间戳截取
 *
 * @param {Number} i 开始时下标
 * @param {DataView} v 数据集
 * @return {Number} 时间戳
 */
export const getDate = (i: number, v: DataView) => {
    var date = '';
    date += v.getUint16(i, true) + '-';
    date += reZero(v.getUint8(i += 2)) + '-';
    date += reZero(v.getUint8(i += 1)) + 'T';
    date += reZero(v.getUint8(i += 1)) + ':';
    date += reZero(v.getUint8(i += 1)) + ':';
    date += reZero(v.getUint8(i += 1)) + '.';
    date += v.getUint32(i += 1, true);
    return new Date(date).getTime()
}

/**
 * 帧数据解析
 *
 * @param {Number} i 开始解析的下标
 * @param {DataView} v DataView 对象
 * @param {ArrayBuffer} r ArrayBuffer对象
 * @return {Object} 解析结果对象 
 */
export const getlevel = (i: number, v: DataView, r: ArrayBuffer) => {
    var AllCount = v.getInt32(i, true);
    var Star = v.getFloat64(i += 4, true);
    var index = v.getInt32(i += 8, true);
    var length = v.getInt32(i += 4, true);
    i += 4;
    var data = new Int16Array(r.slice(i, i += length * 2));
    return {
        AllCount: AllCount,
        index: index,
        Star: Star,
        data: data,
        length: length * 2 + 20,
    }
}

interface ArrayBufferFileHeaderType {
    type?: number,
    long?: number,
    location?: any,
    time?: any,
    data?: Array<any>
}

/**
 * 文件数据解析（不带文件头解析）
 *
 * @param {Number} offset 下标偏移值
 * @param {ArrayBuffer} r 数据源
 * @return {Object} 解析结果对象 
 */
export const GetDates = (offset: number, r: ArrayBuffer) => {
    let i = 0;
    i += offset;
    const v = new DataView(r);
    const d: ArrayBufferFileHeaderType = {};
    d.type = v.getUint8(i);
    d.long = v.getUint32(i += 1, true);
    i += 4;
    if (d.type & 2) {
        d.location = getLocation(i, v);
        i += 18;
    }
    if (d.type & 1) {
        d.time = getDate(i, v);
        i += 11;
    }
    d.data = [];
    var _DataIndex = 0;
    while (d.long > _DataIndex) {
        var _data = getlevel(i, v, r);
        d.data.push(_data);
        _DataIndex += _data.length + i;
    }
    return {
        d,
        offset: i + d.long
    }
}


/**
 * UTF-8 ArrayBuffer 转 字符串
 *
 * @param {ArrayBuffer} array 二进制数据
 * @return {String} 返回结果
 */
export const utf8ArrayToStr = function (array: any): String {
    var out, i: number, len, c;
    var char2, char3;
    out = "";
    len = array.byteLength;
    i = 0;
    while (i < len) {
        c = array[i++];
        switch (c >> 4) {
            case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
                // 0xxxxxxx
                out += String.fromCharCode(c);
                break;
            case 12: case 13:
                // 110x xxxx   10xx xxxx
                char2 = array[i++];
                out += String.fromCharCode(((c & 0x1F) << 6), (char2 & 0x3F));
                break;
            case 14:
                // 1110 xxxx  10xx xxxx  10xx xxxx
                char2 = array[i++];
                char3 = array[i++];
                out += String.fromCharCode(((c & 0x0F) << 12) |
                    ((char2 & 0x3F) << 6) |
                    ((char3 & 0x3F) << 0));
                break;
        }
    }
    return out
};



const sizes = ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'];
export function bytesToSize(bytes: number, index: number = 3): string {
    if (bytes === 0 || !bytes) return '0';
    var k = 1000, i = Math.floor(Math.log(bytes) / Math.log(k));
    return (bytes / Math.pow(k, i)).toPrecision(index) + sizes[i];
}



interface TypedArrayEvent {
    new(sliced: ArrayBuffer): any
}

/**
 * 简单数据截取
 *
 * @export
 * @param {ArrayBuffer} data 数据集
 * @param {number} star 开始下标
 * @param {number} end 结束下标
 * @param {TypedArrayEvent} type 数据类型 以下之一 （Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array, BigInt64Array, BigUint64Array）
 * @return {*}  {TypedArrayEvent} 数据集合
 */
export function getBit(data: ArrayBuffer, star: number, end: number, type: TypedArrayEvent): TypedArrayEvent {
    const sliced = data.slice(star, end);
    return new type(sliced);
}